class Solution
{
public:
    int get(char c)//把字母映射到下标
    {
        if (c == 'Q') return 0;
        if (c == 'W') return 1;
        if (c == 'E') return 2;
        return 3;
    }

    bool check(vector<int> &tot, vector<int> &sum, int target)//判断滑动窗口中的内容是否满足条件
    {
        for (int i = 0; i < 4; i ++ )
            if (tot[i] - sum[i] > target) //在这个窗口外的字符数量是不是大于n/4的是的话返回false
                return false;
        return true;
    }

    int balancedString(string s)
    {
        vector<int> tot(4);
        for (auto c : s) tot[get(c)] ++ ;//统计每个字符出现的次数
        int n = s.size();

        if (tot[0] == n / 4 && tot[1] == n / 4 && tot[2] == n / 4) return 0;//不用改的情况

        int res = n;
        vector<int> sum(4);//区间里每个字符出现的数量
        for (int i = 0, j = 0; i < n; i ++ )
        {
            sum[get(s[i])] ++ ;
            while (j <= i && check(tot, sum, n / 4))
            {
                res = min(res, i - j + 1);
                sum[get(s[j])] -- ;
                j ++ ;
            }
        }

        return res;
    }
};
//滑动窗口的思路是,在窗口内的字母随便动,在窗口外的字符一定小于等于n/4这样,窗口是结尾为i位置的时候最靠近i且能满足更改的的j位置

